use std::{env, fs};
use std::fs::File;
use std::io::{Read, BufReader, Write};
use sha2::{Sha256, Digest};
use serde::{Serialize, Deserialize};

fn calculate_sha256(file_path: &str) -> Result<String, std::io::Error> {
    // 创建 SHA256 hasher
    let mut hasher = Sha256::new();

    // 用 BufReader 高效读取文件
    let file = File::open(file_path)?;
    let mut reader = BufReader::new(file);

    // 缓冲区大小（可根据需要调整）
    let mut buffer = [0; 4096];

    // 逐块读取并更新哈希
    loop {
        let bytes_read = reader.read(&mut buffer)?;
        if bytes_read == 0 {
            break;
        }
        hasher.update(&buffer[..bytes_read]);
    }

    // 生成最终哈希值
    let result = hasher.finalize();
    Ok(format!("{:x}", result))
}

pub fn launch() {
    let path = env::current_dir().unwrap();
    let mut url = "".to_string();
    let args: Vec<String> = env::args().collect();
    if let Ok(entries) = fs::read_dir(&path) {
        for entry in entries {
            if args.len() > 1 {
                break;
            }
            if let Ok(entry) = entry {
                let file_path = entry.path();
                let file_name = file_path.file_name().unwrap().to_string_lossy();
                println!("File: {}", file_name);

                if file_name.ends_with("zip") {
                    url = file_name.to_string();
                }
            }
        }
    }

    println!("url is {}", &url);
    if url == "".to_string() {
        url = args[1].clone();
    }
    let size = get_zip_file_size(&url).unwrap().to_string();

    let json_file = "hmdiagnostics-meta-5.0-hmdiagnostics-single-12.json".to_string();

    let res = fs::remove_file(&json_file);
    if let Err(_) = res {

    }

    match calculate_sha256(&url) {
        // Ok(hash) => println!("SHA256 checksum: {}", hash),
        Ok(hash) => {
            let words: Vec<String> = url.split("/").into_iter().map(|w| w.to_string()).collect();
            url = words[words.len() - 1].clone();
            let app_result = AppResult::new(&url, &size, &hash);
            let json = serde_json::to_string(&app_result).unwrap();
            println!("{}", &json);
            fs::write(&json_file, &json).unwrap();
        },
        Err(e) => eprintln!("Error: {}", e),
    }
}
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
struct AppResult {
    app_version: String,
    url: String,
    size: String,
    checksum: String,
}

impl AppResult {
    pub fn new(url: &str, size: &str, checksum: &str) -> Self {
        Self {
            app_version: "1.0.0".to_string(),
            url: url.to_string(),
            size: size.to_string(),
            checksum: checksum.to_string(),
        }
    }
}

fn get_zip_file_size(path: &str) -> Result<u64, std::io::Error> {
    let metadata = fs::metadata(path)?;
    let size = metadata.len();
    Ok(size)
}